//
//  QICameraViewController.swift
//  月升
//
//  Created by 拉利法 on 2024/7/10.
//

import UIKit
import AVFoundation
import AssetsLibrary
import CoreMotion



protocol WWXHCameraViewControllerDelegate {
    func cameraViewController(_ : QICameraViewController, didFinishPickingImage image: UIImage)
}

class QICameraViewController: QIBaseViewController {
    
    
    // session 用来执行输入设备和输出设备之间的数据传递
    var session: AVCaptureSession = AVCaptureSession()
    // 输入设备
    var videoInput: AVCaptureInput?
    // 照片输出流
    var stillImageOutput: AVCaptureStillImageOutput = AVCaptureStillImageOutput()
    // 预览图层
    var previewLayer: AVCaptureVideoPreviewLayer?
    // 管理者对象
    var motionManger: CMMotionManager = CMMotionManager()
    // 拍照点击按钮
    var takePhotoBtn: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    
    var delegate: WWXHCameraViewControllerDelegate?
    
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        DispatchQueue.global(qos: .userInitiated).async {
            self.session.startRunning()
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        session.stopRunning()
        if (motionManger.isDeviceMotionActive) {
            motionManger.stopDeviceMotionUpdates()
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .black
        
        setupAVCaptureSession()
        setUpUI()
        switchCameraSegmentedControlClick()
    }
    
    
    func setupAVCaptureSession() {
        self.session.sessionPreset = AVCaptureSession.Preset.photo
        let device = AVCaptureDevice.default(for: AVMediaType.video)
        
        do {
            // 锁定设备之后才能修改设置,修改完再锁上
            try device?.lockForConfiguration()
            device?.unlockForConfiguration()
        } catch (let error){
            print(error)
        }
        
        do {
            try videoInput = AVCaptureDeviceInput(device: device!)
        } catch (let error){
            print(error)
        }
        // 输出设置 AVVideoCodecJPEG  -> 输出jpeg格式图片
        stillImageOutput.outputSettings = [AVVideoCodecJPEG: AVVideoCodecKey]
        session.canAddInput(videoInput!) ? session.addInput(videoInput!) : ()
        session.canAddOutput(stillImageOutput) ? session.addOutput(stillImageOutput) : ()
        // 设置为高分辨率
//        if session.canSetSessionPreset(AVCaptureSession.Preset(rawValue: "AVCaptureSessionPreset3840x2160")) {
//            session.sessionPreset = AVCaptureSession.Preset(rawValue: "AVCaptureSessionPreset3840x2160")
//        }
        
        
        //初始化预览图层
        previewLayer = AVCaptureVideoPreviewLayer(session: session)
        previewLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        previewLayer?.frame = CGRect(x: 0, y: NAV_HEIGHT, width: SCREEN_WIDTH, height: SCREEN_HEIGHT - NAV_HEIGHT - 200)
        if let previewLayer_ = previewLayer {
            self.view.layer.addSublayer(previewLayer_)
        }
    }
    
    
    func setUpUI() {
        
        let headerView = UIView()
        headerView.frame = CGRect(x: 0, y: 0, width: SCREEN_WIDTH, height: NAV_HEIGHT)
        headerView.backgroundColor = ColorWithStr("#FFD1D6")
        view.addSubview(headerView)
        
        let coverImageView = UIImageView(image: UIImage(named: "头型"))
        coverImageView.frame = CGRect(x: 0, y: NAV_HEIGHT, width: SCREEN_WIDTH, height: SCREEN_HEIGHT - NAV_HEIGHT - 200)
        view.addSubview(coverImageView)
        
        let footView = UIView()
        footView.frame = CGRect(x: 0, y: SCREEN_HEIGHT - 200, width: SCREEN_WIDTH, height: 200)
        footView.backgroundColor = .black
        view.addSubview(footView)
        
        // 初始化相机按钮
        takePhotoBtn.addTarget(self, action: #selector(takePhoto), for: UIControl.Event.touchUpInside)
        takePhotoBtn.setImage(UIImage(named: "拍照"), for: UIControl.State.normal)
        takePhotoBtn.center = CGPoint(x: SCREEN_WIDTH * 0.5, y: 100)
        footView.addSubview(takePhotoBtn)
        
        let flipBtn = UIButton().then {
            $0.frame = CGRect(x: SCREEN_WIDTH - 60, y: 0, width: 40, height: 40)
            $0.centerY = takePhotoBtn.centerY
            $0.setImage(UIImage(named: "翻转镜头"), for: .normal)
            $0.addTarget(self, action: #selector(flipBtnClick), for: .touchUpInside)
        }
        footView.addSubview(flipBtn)
        
    }
    
    @objc private func flipBtnClick(btn: UIButton) {
        btn.isSelected = !btn.isSelected
        
        let desiredPosition = btn.isSelected ? AVCaptureDevice.Position.back : AVCaptureDevice.Position.front
        for d in AVCaptureDevice.devices(for: AVMediaType.video) {
            if ((d ).position == desiredPosition) {
                previewLayer?.session?.beginConfiguration()
                do {
                    let input = try AVCaptureDeviceInput(device: d )
                    for oldInput in (previewLayer?.session?.inputs)! {
                        previewLayer?.session?.removeInput(oldInput )
                    }
                    previewLayer?.session?.addInput(input)
                    previewLayer?.session?.commitConfiguration()
                } catch (let error) {
                    print(error)
                }
                break
            }
        }
    }
    
    func avOrientationForDeviceOrientation(deviceOrientation: UIDeviceOrientation) -> AVCaptureVideoOrientation? {
        if (deviceOrientation == UIDeviceOrientation.landscapeLeft) {
            return AVCaptureVideoOrientation.landscapeRight
        } else if (deviceOrientation == UIDeviceOrientation.landscapeRight){
            return AVCaptureVideoOrientation.landscapeLeft
        } else {
            return nil
        }
    }
    
    @objc func takePhoto() {
        
        guard let stillImageConnection = stillImageOutput.connection(with: AVMediaType.video) else {
            print("相机初始化失败")
            return
        }
        let curDeviceOrientation = UIDevice.current.orientation
        if let avcaptureOrientation = self.avOrientationForDeviceOrientation(deviceOrientation: curDeviceOrientation) {
            stillImageConnection.videoOrientation = avcaptureOrientation
            stillImageConnection.videoScaleAndCropFactor = 1
        }
        stillImageOutput.captureStillImageAsynchronously(from: stillImageConnection) {[unowned self] (imageDataSampleBuffer, error) in
            
            if let error_ = error {
                print(error_)
                return
            }
            guard let _ = imageDataSampleBuffer else {
                return
            }
            
            if let jpegData = AVCaptureStillImageOutput.jpegStillImageNSDataRepresentation(imageDataSampleBuffer!) {
                if let tempImage = UIImage(data: jpegData, scale: 1) {
                    if let tempCgImage = tempImage.cgImage {
                        let image = UIImage(cgImage: tempCgImage, scale: 1, orientation: UIImage.Orientation.right)
                        
                        self.delegate?.cameraViewController(self, didFinishPickingImage: image)
                        print("拍照完成")
//                        self.dismiss(animated: true, completion: nil)
                        self.navigationController?.popViewController(animated: true)
                    }
                }
            }
        }
        
    }
    
    
    
    @objc func switchCameraSegmentedControlClick() {
        let desiredPosition = AVCaptureDevice.Position.front
        for d in AVCaptureDevice.devices(for: AVMediaType.video) {
            if ((d ).position == desiredPosition) {
                previewLayer?.session?.beginConfiguration()
                do {
                    let input = try AVCaptureDeviceInput(device: d )
                    for oldInput in (previewLayer?.session?.inputs)! {
                        previewLayer?.session?.removeInput(oldInput )
                    }
                    previewLayer?.session?.addInput(input)
                    previewLayer?.session?.commitConfiguration()
                } catch (let error) {
                    print(error)
                }
                break
            }
        }
    }

  

}
